一些 OpenSSL 工具可以为证书或证书请求添加扩展。扩展段的每一行都具有如下的形式:
extension_name=[critical,] extension_options
若出现了 critical
那么扩展为关键的(critical)。
extension_options 的格式依照 extension_name 的内容而定。
有四种主要的扩展:字符串扩展,多值扩展,原始扩展,任意扩展。
字符串扩展就是简单地具有值本身,或者或者值的方法。
举例:
nsComment="This is a Comment"
多值扩展具有一个短形式和一个长形式。短形式为一个名称和值的列表:
basicConstraints=critical,CA:true,pathlen:1
长形式允许在一个单独的段中放置值:
basicConstraints=critical,@bs_section
[bs_section]
CA=true
pathlen=1
两种形式等价。
原始扩展的语法由扩展的代码管理:比如说,它可以包含一个多段的数据。正确的语法由扩展代码定义:举例来说,参见证书策略扩展。
若一个扩展类型不被支持,那么必须使用 任意扩展语法,参见 任意扩展 节了解更多详情。
下面的小节详细的描述了每个支持的扩展。
该扩展为多值扩展,它指出了一个证书是否为 CA 证书。首个(必要的)名称为 CA
,其后跟随 TRUE
或 FALSE
。若 CA
为 TRUE
,那么在其后可以包含一个 pathlen
选项,其后跟随一个非负值。
basicConstraints=CA:TRUE
basicConstraints=CA:FALSE
basicConstraints=critical, CA:TRUE, pathlen:0
一个 CA 证书必须包含 basicConstraints
值,且 CA
字段必须设置为 TRUE
。一个终点用户证书(end user certificate)必须将 CA
设置为 FALSE
,或者完全排除该扩展。有些软件可能要求终点实体证书(end entity certificate)必须包含 CA
设置为 FALSE
的 basicConstraints
。
pathlen 参数指出该证书所在证书链中,其下游还能出现的 CA 的最大数量。所以如果你将一个 CA 的 pathlen
设置为 0,那么它仅可以被用于签发终点用户证书,而非其它 CA。
密钥用途是一个多值扩展,包含由允许密钥用途的名称所组成的一个列表。
支持的名称有:digitalSignature
、nonRepudiation
、keyEncipherment
、dataEncipherment
、keyAgreement
、keyCertSign
、cRLSign
、encipherOnly
、decipherOnly
。
举例:
keyUsage=digitalSignature, nonRepudiation
keyUsage=critical, keyCertSign
该扩展由一系列用法的列表组成,它指出了证书的公钥可使用的意图。
值可以是对象短名,或者是点分隔的数值形式的 OID。虽然可以使用任意 OID,但仅有特定的值有意义。实际上来说,下面的 PKIX、NS、MS 值才是有意义的:
值 | 含义 |
---|---|
serverAuth |
SSL/TLS 网络服务器验证 |
clientAuth |
SSL/TLS 网络客户端验证 |
codeSigning |
代码签名 |
emailProtection |
电子邮件保护(S/MIME) |
timeStamping |
可信时间戳 |
OCSPSigning |
OCSP 签名 |
ipsecIKE |
ipsec 互联网密钥交换 |
msCodeInd |
微软个人代码签名(authenticode) |
msCodeCom |
微软商业代码签名(authenticode) |
msCTLsign |
微软可信列表签名 |
msEFS |
微软加密文件系统 |
举例:
extendedKeyUsage=critical, codeSigning, 1.2.3.4
extendedKeyUsage=serverAuth, clientAuth
字符串扩展,可接受两种可能的值。要么是字符 hash
,它会自动依照 RFC3280 中的指导;或者是一个十六进制字符串,它给出要包含的扩展值。强烈不建议使用十六进制字符串。
举例:
subjectKeyIdentifier=hash
授权密钥标识符扩展允许两种选项。keyid
和 issuer
:两者均可以接受可选值 always
。
若出现了 keyid
选项,那么将尝试从父级证书中复制主体密钥标识符。若值设置为 always
,那么当选项失败时,返回错误。
issuer
选项从签发者证书中拷贝签发者和序列号。当指定了 always
后,总是执行该操作;否则仅在 keyid
选项不存在或执行失败后被执行。
举例:
authorityKeyIdentifier=keyid, issuer
主体替代名扩展允许配置文件中包含多个字面值。它们包含 email
(电子邮件地址)、URI
统一资源定位符、DNS
(DNS 域名)、RID
(一个已注册的ID:OBJECT IDENTIFIER)、IP
(IP 地址)、dirName
(可辨识名)、otherName
。
email
选项包含一个特殊的 copy
值。它将会自动包含扩展中包含在证书主体名中的电子邮件地址。
用于 IP
选项的 IP 地址可以是 IPv4 格式也可以是 IPv6 格式。
dirName
的值应该指向一个段,该段中包含了用一组名称值对组成的可辨识名。可以在名称前添加一个加号 +
来构成多值 AVA。
otherName
可以包含具有 OID 的任意数据:值应该为 OID,一个分号 ;
,以及其内容,它的格式应该为标准 ASN1_generate_nconf(3) 格式。
举例:
subjectAltName=email:copy,email:[email protected],URI:http://my.url.here/
subjectAltName=IP:192.168.7.1
subjectAltName=IP:13::17
subjectAltName=email:[email protected],RID:1.2.3.4
subjectAltName=otherName:1.2.3.4;UTF8:some other identifier
subjectAltName=dirName:dir_sect
[dir_sect]
C=UK
O=My Organization
OU=My Unit
CN=My Name
签发者替代名选项支持全部主体替代名选项的字面选项。它不支持 email:copy
选项,因为这么做没有意义。但该选项支持 issuer:copy
选项,该选项会从签发者证书中拷贝全部可能存在的主体替代名。
举例:
issuerAltName = issuer:copy
授权信息访问扩展给出了如何获取与 CA 相关的特定信息的细节。它的语法为 accessOID;location,其中的 location 的语法和主体替代名的一样(但不支持 email:copy
)。acessOID 可以是任何有效的 OID,但仅有特定的值是有意义的,比如说 OCSP
和 caIssuers
。
举例:
authorityInfoAccess = OCSP;URI:http://ocsp.my.host/
authorityInfoAccess = caIssuers;URI:http://my.ca/ca.html
该扩展为多值扩展,其为与主体替代名相同形式的名称值对;或者一个单值,指向一个段名,该段中包含了所有分发点字段。
对于名称值对来说,会将一对 DistrbutionPoint 与 fullName 设置为给定值,同时忽略 cRLissuer 以及 reasons 字段。
在单一选项中,其值指向了包含每个字段的段。在该段中:
若名称为 fullname
,那么字段值应该包含分发点的全名,其具有与主体替代名相同的格式。
若名称为 relativename
,那么字段值应该包含一个段名,其内容表示了要置入该字段的 DN 片段。
若出现了 CRLIssuer
,那么字段应该包含主体替代名格式的值。
若名称为 reason
,那么值应该为用逗号分隔的原因。有效的原因为:keyCompromise
、CACompromise
、affiliationChanged
、superseded
、cessationOfOperation
、certificateHold
、privilegeWithdrawn
、AACompromise
。
简单案例:
crlDistributionPoints=URI:http://myhost.com/myca.crl
crlDistributionPoints=URI:http://my.com/my.crl,URI:http://oth.com/my.crl
完整分发点案例:
crlDistributionPoints=crldp1_section
[crldp1_section]
fullname=URI:http://myhost.com/myca.crl
CRLissuer=dirName:issuer_sect
reasons=keyCompromise, CACompromise
[issuer_sect]
C=UK
O=Organisation
CN=Some Name
该扩展应该仅在 CRL 中出现。它是一个多值扩展,其语法与 CRL 分发点扩展的 section 所指向的扩展的语法类似,也有细微的不同。
该扩展不识别 reasons
和 CRLissuer
。+
接受 onlysomereasons
。其值的格式与 CRL 分发点的 reasons
字段相同。
也接受 onlyuser
、onlyCA
、onlyAA
、indirectCRL
,它们的值应为布尔值(TRUE
或 FALSE
)来指出对应字段的值。
举例:
issuingDistributionPoint=critical, @idp_section
[idp_section]
fullname=URI:http://myhost.com/myca.crl
indirectCRL=TRUE
onlysomereasons=keyCompromise, CACompromise
[issuer_sect]
C=UK
O=Organisation
CN=Some Name
该扩展为原始扩展。该扩展的全部字段可以使用恰当的语法设置。
如果你遵循 PKIX 推荐,且仅是哟ing一个 OID,那么只要包括那个 OID 的值就可以了。多个 OID 之间可以用逗号分隔,比如:
certificatePolicies= 1.2.4.5, 1.1.3.4
若你希望包含修饰词(qualifier),那么策略 OID 和修饰词必须在一个单独的段中指定:使用 @section 语法,而非 OID 值的字面值。
所指向的段必须包括用 policyIdentifier
定义的策略 OID,cPSuri 修饰词可以通过下方的语法包含进来:
CPS.nnn=value
userNotice 修饰词可以使用下方的语法:
userNotice.nnn=@notice
userNotice 修饰词的值定义在相关段中。该段可以包含 explicityText
、organization
、noticeNumbers
选项。explicityText
和 organization
为文本字符串,noticeNumbers
为逗号分隔的数字所组成的列表。organization
和 noticeNumbers
两者(若存在,则)为必包含选项。若你在 IE5 中使用了 userNotice
选项,那么必须在顶层指定 ia5org
选项来修改编码:否则它将不能被正确解析。
举例:
certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect
[polsect]
policyIdentifier = 1.3.5.8
CPS.1="http://my.host.name/"
CPS.2="http://my.your.name/"
userNotice.1=@notice
[notice]
explicitText="Explicit Text Here"
organization="Organisation Name"
noticeNumbers=1,2,3,4
ia5org
选项改变了 organization
字段的类型。在 RFC2459 中它仅可以为 DisplayText 类型。在 RFC3280 中,同样也允许 IA5String。一些软件(比如部分版本的 MSIE)可能会要求 ia5org。
ASN1 类型的 explicityText
可以这样组成:UTF8
或 BMP
或 VISIBLE
,一个冒号,一个字符串。举例:
[notice]
explicityText="UTF8:Explicity Text Here"
该扩展为多值扩展,由 requireExplicityPolicy
或 inhibitPolicyMapping
,以及一个非负整数值组成。至少要出现一个组分。
举例:
policyConstraints = requireExplicitPolicy:3
名称约束扩展是一个多值扩展。名称应该应该以单词 permitted
或者 excluded
开头,后跟随一个分号 ;
。余下的名称和值遵循 subjectAltName
的语法,除了不支持 email:copy
,且 IP
的形式应该由 IP 地址和子网掩码以及中间的斜线 /
分开。
举例:
nameConstraints=permitted;IP:192.168.0.0/255.255.0.0
nameConstraints=permitted;email:.somedomain.com
nameConstraints=excluded;email:.com
下面的扩展为非标准、Netscape 特定,且大概率废弃的。在新应用中使用它们是不被鼓励的。
Netscape 注释(nsComment)是一个字符串扩展,包含了一个注释,该注释会在一些浏览器浏览证书时被显示出来。
举例:
nsComment = "Some Random Comment"
该种类下,还有被支持的其他扩展为:nsBaseUrl
、nsRevocationUrl
、nsCaRevocationUrl
、nsRenewalUrl
、nsCaPolicyUrl
,nsSslServerName
。
若一个扩展不被 OpenSSL 代码支持,那么它必须以任意扩展格式编码。也可以对支持的扩展使用任意编码格式。对于给定的扩展类型,必须十分小心地检查,以保证数据被正确格式化了。
有两种方法编码任意扩展。
第一种方法是使用单词 ASN1
后面跟随扩展内容,其语法与 ASN1_generate_nconf(3) 相同。举例来说:
1.2.3.4=critical,ASN1:UTF8String:Some random data
1.2.3.4=ASN1:SEQUENCE:seq_sect
[seq_sect]
field1 = UTF8:field1
field2 = UTF8:field2
也可以使用单词 DER
在任何扩展中包括 raw 编码的数据。
1.2.3.4=critical,DER:01:02:03:04
1.2.3.4=DER:01020304
DER 后跟随的值是六进制 dump 的 DER 编码的扩展。任何扩展可以用这种格式来覆盖默认的行为。举例来说:
basicConstraints=critical,DER:00:01:02:03
不保证一个特定的实现会处理给定的扩展。因此有些时候证书会被用于禁止使用的情况,仅仅是因为特定的应用无法辨别或不重视相关扩展的值。
DER 和 ASN1 选项应该谨慎使用。若不小心会创建完全无效的扩展。
若一个扩展为多值扩展,且一个字段值必须包含一个逗号,则必须使用长格式,否则逗号会被误认为是字段分隔符。举例来说:
subjectAltName=URL:ldap://somehost.com/CN=foo,OU=bar
会产生错误,但等价形式:
subjectAltName=@subject_alt_section
[subject_alt_section]
subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar
是有效的。
介于 OpenSSL conf 库的行为,相同的字段名在同一个段中仅能出现一次。这意味者:
subjectAltName=@alt_section
[alt_section]
email=steve@here
email=steve@there
仅会获得最后的值。可以用下面的形式绕行:
[alt_section]
email.1=steve@here
email.2=steve@there